package com.legendshop.code.freemarker.builder;

import java.util.List;
import java.util.Map;

import com.legendshop.code.config.Config;
import com.legendshop.code.config.Table;
import com.legendshop.code.db.Column;
import com.legendshop.code.db.DbSchemaProvider;
import com.legendshop.code.freemarker.AbstractBulidTemplet;
import com.legendshop.code.freemarker.BulidTemplet;
import com.legendshop.code.freemarker.PackageConfigUtil;
import com.legendshop.code.freemarker.model.SQLStatement;
import com.legendshop.code.util.Templet;

@Templet
public class SQLStatementBulidTemplet extends AbstractBulidTemplet {

	public SQLStatementBulidTemplet(){
		
	}
	
	@Override
	public boolean buildSourceFile(String tableName) {
		Config config = Config.getInstance();
		String outputDir = config.getPath() + BulidTemplet.MAIN_PATH + PackageConfigUtil.getModelPackagePath();
		String templateFileName = "SQLStatement.ftl";

		Map<String, Object> paramMap = config.getContextMap(tableName);
		Table table = DbSchemaProvider.getTableDefinition(tableName);
		paramMap.put("statement", createSQLStatement(table));

		String fileName = table.getTableName() + ".sql";

		boolean result = super.buildJavaFile(templateFileName, paramMap, outputDir, fileName,false);

		//System.out.println("End Build HibernateEntityXml File.\n");
		return result;
	}
	
	private SQLStatement createSQLStatement(Table table){
		SQLStatement statement = new SQLStatement();
		StringBuilder allColumns = appenedColumns(table.getColumnList());
		Column idColumn = getIdColumn(table.getColumnList());
		
		if(idColumn == null){
			throw new RuntimeException("ID must set for table " + table.getTableName());
		}
		
		StringBuilder insertSql = new StringBuilder("insert into ");
		insertSql.append(table.getTableName()).append("(").append(allColumns).append(") values (");
		for (int i =0; i <table.getColumnList().size(); i ++ ) {
			insertSql.append("?,");
		}
		insertSql.setLength(insertSql.length() - 1);
		insertSql.append(")");
		statement.setInsert(insertSql.toString());
		
		statement.setDelete("delete from " + table.getTableName() + " where " +idColumn.getColumnName() + " = ?");
		
		statement.setGetById("select " + allColumns.toString() + " from " + table.getTableName()   +" where " +idColumn.getColumnName() + " = ?" );
		
		statement.setGetAdJavaNameById("select " + appenedColumnsAsJavaName(table.getColumnList()) + " from " + table.getTableName()  + " where " +idColumn.getColumnName() + " = ?");
		
		String updatCriteria = createUpdateCriteria(table.getColumnList(), idColumn).toString();
		statement.setUpdate("update " + table.getTableName() + "set " + updatCriteria);
		return statement;
	}
	
	private StringBuilder createUpdateCriteria(List<Column> columnList, Column idColumn){
		StringBuilder sb = new StringBuilder();
		for (Column column : columnList) {
			if(!column.isPrimaryKeyColumn()){
				sb.append(column.getColumnName()).append(" = ?,");
			}
		}
		if(sb.length() > 0){
			sb.setLength(sb.length() - 1);
		}
		
		sb.append(" where ").append(idColumn.getColumnName()).append(" = ?");
		return sb;
	}
	
	private Column getIdColumn(List<Column> columnList){
		for (Column column : columnList) {
			if(column.isPrimaryKeyColumn()){
				return column;
			}
		}
		return null;
	}
	
	private StringBuilder appenedColumns(List<Column> columnList){
		StringBuilder columns = new StringBuilder();
		
		for (int i = 0; i < columnList.size() -1; i++) {
			Column column = columnList.get(i);
			columns.append(column.getColumnName()).append(",");
		}
		columns.append(columnList.get(columnList.size() -1).getColumnName());
		return columns;
	}
	
	private StringBuilder appenedColumnsAsJavaName(List<Column> columnList){
		StringBuilder columns = new StringBuilder();
		
		for (int i = 0; i < columnList.size() -1; i++) {
			Column column = columnList.get(i);
			columns.append(column.getColumnName() + " as " + column.getJavaName() ).append(",");
		}
		Column lastColumn = columnList.get(columnList.size() -1);
		columns.append(lastColumn.getColumnName()).append(" as " ).append(lastColumn.getJavaName());
		return columns;
	}
	
}
